package com.startest.sms.config;


import com.startest.sms.dao.UserMapper;
import com.startest.sms.pojo.Permission;
import com.startest.sms.pojo.Role;
import com.startest.sms.pojo.User;
import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;


/**
 * Created by cly on 2018/12/26.
 * 自定义Realm
 */

public class UserRealm extends AuthorizingRealm {

    private static final Logger logger = LoggerFactory.getLogger(UserRealm.class);

    @Autowired
    private UserMapper userMapper;

    /**
     * 授权：授予角色和权限
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        logger.debug("--开始授予角色和权限--");
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        User user = (User)subject.getPrincipal();

        ArrayList<String> permissions = new ArrayList<>();
        ArrayList<String> roles = new ArrayList<>();
        //通过用户 获取角色list
        List<Role> roleList = userMapper.selectRolesByUser(user);
        for(Role role : roleList){
            //循环添加
            roles.add(role.getRole());
            //通过角色 获取权限list
            List<Permission> permList = userMapper.selectPermsByRole(role);
            for(Permission permission : permList){
                //循环添加
                permissions.add(permission.getPermission());
            }
        }
        simpleAuthorizationInfo.addRoles(roles);
        simpleAuthorizationInfo.addStringPermissions(permissions);
        return simpleAuthorizationInfo;
    }

    /**
     * 账户密码登录身份认证
     * @param token
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {

        String username = null;
        if(token instanceof UsernamePasswordToken){
            //.getPrincipal()返回在身份验证过程中提交的账户标识
            username = (String) token.getPrincipal();
            logger.info("用户登录认证：验证当前Subject时获取的token为："+
                    ReflectionToStringBuilder.toString(token, ToStringStyle.MULTI_LINE_STYLE));
        }else{
            return null;
        }
        User user = userMapper.selectUserByName(username);
        logger.debug("用户登录认证信息user为："+user);
        if(user==null){
            throw new UnknownAccountException("账户或密码错误");
        }
        if(user.getState()==0){
            throw new DisabledAccountException("用户未激活，请激活用户");
        }
        if(user.getState()==2){
            throw  new LockedAccountException("账号被锁定，请联系管理员");
        }
        return new SimpleAuthenticationInfo(username,user.getUserPwd(),getName());

    }

    @Override
    public boolean supports(AuthenticationToken token){
        return token instanceof UsernamePasswordToken;
    }

}
